package com.invengo.module_check.ui.fragment.search;

import android.annotation.SuppressLint;
import android.app.Application;
import android.os.Build;

import androidx.annotation.NonNull;
import androidx.databinding.ObservableArrayList;
import androidx.databinding.ObservableField;
import androidx.databinding.ObservableInt;
import androidx.databinding.ObservableList;

import com.invengo.library_db.entity.module_check.BookBean;
import com.invengo.library_rfid.classify.AnalyzeImpl;
import com.invengo.library_rfid.classify.RFIDCallBackListener;
import com.invengo.library_rfid.entity.TagInfo;
import com.invengo.module_check.BR;
import com.invengo.module_check.R;
import com.invengo.module_check.data.repsitory.business.BusinessRepsitory;
import com.invengo.module_check.ui.fragment.search.item.BookSearchItemViewModel;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import java8.util.stream.StreamSupport;
import me.goldze.mvvmhabit.base.BaseViewModel;
import me.goldze.mvvmhabit.binding.command.BindingCommand;
import me.goldze.mvvmhabit.bus.RxBus;
import me.goldze.mvvmhabit.bus.event.SingleLiveEvent;
import me.goldze.mvvmhabit.utils.RxUtils;
import me.goldze.mvvmhabit.utils.ToastUtils;
import me.tatarka.bindingcollectionadapter2.ItemBinding;

public class BookSearchViewModel extends BaseViewModel<BusinessRepsitory> {

    public RFIDCallBackListener rfidService = new RFIDCallBackListener(AnalyzeImpl.TO_BOOK, tagInfo -> onScanResult(tagInfo), state -> isReading.set(state));
    public ObservableInt findCount = new ObservableInt(0);
    public ObservableList<BookSearchItemViewModel> serchBookItemList = new ObservableArrayList<>();
    public ItemBinding<BookSearchItemViewModel> serchBookitemBinding = ItemBinding.of(BR.viewModel, R.layout.item_search_book);

    public ObservableField<String> findBookName = new ObservableField<>();
    public ObservableField<Boolean> showDialog = new ObservableField<>();
    public ObservableField<String> findBarcode = new ObservableField<>();

    public BookSearchViewModel(@NonNull Application application) {
        super(application, BusinessRepsitory.getInstance());
        registerRFID(rfidService);
        registerBookBeans();
    }


    public UIChangeObservable ui = new UIChangeObservable();

    public class UIChangeObservable {
        public SingleLiveEvent<Integer> addBookEvent = new SingleLiveEvent<>();
    }

    public void onScanResult(TagInfo tagInfo) {
        switch (tagInfo.getRfidModel()) {
            case TID:
                if (tagInfo.getScanModel() == AnalyzeImpl.TO_SHELF) {
//                    getShelfByTid(tagInfo.getTag());
                } else
                    getBookByTid(tagInfo.getTag());
                break;
            case EPC:
            case U_DATA:
                if (tagInfo.getScanModel() == AnalyzeImpl.TO_SHELF) {
//                    getShelfByCode(tagInfo.getTag());
                } else
                    getBookByCode(tagInfo.getTag());
                break;
        }
    }

    /**
     * 获取position的方式有很多种,indexOf是其中一种，常见的还有在Adapter中、ItemBinding.of回调里
     *
     * @return
     */
    public int getPosition(BookSearchItemViewModel item) {
        return serchBookItemList.indexOf(item);
    }


    /**
     * 按Tid查询书本
     *
     * @param tid 标签
     */
    private void getBookByTid(String tid) {
        model.getBookByTid(tid)
                .compose(RxUtils.applySchedulersIO(getLifecycleProvider(), this))
                .subscribe(bookBean -> checkItem(bookBean));
    }


    /**
     * 按Tid查询书本
     *
     * @param code 标签
     */
    private void getBookByCode(String code) {
        model.getBookByCode(code)
                .compose(RxUtils.applySchedulersIO(getLifecycleProvider(), this))
                .subscribe(bookBean -> checkItem(bookBean));
    }

    private void checkItem(BookBean bean) {
        if (serchBookItemList.size() == 0) {
            ToastUtils.showShort("请先添加图书");
            return;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            serchBookItemList.stream().filter(itemList -> itemList.book.getValue().getTid().equals(bean.getTid())).findAny().ifPresent(itemViewModel -> {
                playOtherSound();
                findCount.set(findCount.get() + 1);
                itemViewModel.isFind.postValue(true);
                findBookName.set(bean.getBookName());
                findBarcode.set(bean.getBarCode());
                showDialog();
            });
        } else {
            StreamSupport.stream(serchBookItemList).filter(itemList -> itemList.book.getValue().getTid().equals(bean.getTid())).findAny().ifPresent(itemViewModel -> {
                playOtherSound();
                findCount.set(findCount.get() + 1);
                itemViewModel.isFind.postValue(true);
                findBookName.set(bean.getBookName());
                findBarcode.set(bean.getBarCode());
                showDialog();
            });
        }
    }

    private void showDialog() {
        showDialog.set(true);
        Observable.timer(1500, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(aLong -> showDialog.set(false));
    }


    public BindingCommand addBookCommand = new BindingCommand(() -> {
        ui.addBookEvent.call();
    });

    private void registerBookBeans() {
        RxBus.getDefault().toObservable(List.class)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(list -> {
                    serchBookItemList.clear();
                    findCount.set(0);
                    for (Object bean : list) {
                        addItem((BookBean) bean);
                    }
                });
    }

    /**
     * 添加项目
     *
     * @param bean 豆
     */

    private void addItem(BookBean bean) {
        BookSearchItemViewModel bookSearchItemViewModel = new BookSearchItemViewModel(this, bean);
        serchBookItemList.add(bookSearchItemViewModel);
    }


    public BindingCommand finishSearch = new BindingCommand(() -> {
        getUC().getFinishEvent().call();
    });

    /**
     * 单层下架清理
     */
    public BindingCommand cleanAllBooks = new BindingCommand(() -> {
        cleanRFIDCache();
        serchBookItemList.clear();
    });

    public List<BookBean> getUnfindList() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return serchBookItemList.stream()
                    .map(itemViewModel -> {
                        BookBean value = itemViewModel.book.getValue();
                        value.setRemark(itemViewModel.isFind.getValue() ? "已找到" : "未找到");
                        return value;
                    })
                    .collect(Collectors.toList());
        } else {
            return StreamSupport.stream(serchBookItemList)
                    .map(itemViewModel -> {
                        BookBean value = itemViewModel.book.getValue();
                        value.setRemark(itemViewModel.isFind.getValue() ? "已找到" : "未找到");
                        return value;
                    })
                    .collect(java8.util.stream.Collectors.toList());
        }
    }

}
